package com.easylinkin.linkappapi.videomonitor.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.alarm.entity.Alarm;
import com.easylinkin.linkappapi.alarm.service.AlarmService;
import com.easylinkin.linkappapi.common.utils.DateUtil;
import com.easylinkin.linkappapi.device.entity.Device;
import com.easylinkin.linkappapi.device.mapper.DeviceMapper;
import com.easylinkin.linkappapi.deviceservice.service.DeviceServiceService;
import com.easylinkin.linkappapi.linkage.entity.LinkageLog;
import com.easylinkin.linkappapi.linkage.mapper.LinkageLogMapper;
import com.easylinkin.linkappapi.openapi.dto.ApiDownResultDTO;
import com.easylinkin.linkappapi.ruleengine.entity.RuleExecution;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.tenant.entity.LinkappTenant;
import com.easylinkin.linkappapi.tenant.mapper.LinkappTenantMapper;
import com.easylinkin.linkappapi.videomonitor.entity.DeviceVideoMonitor;
import com.easylinkin.linkappapi.videomonitor.entity.DeviceVideoMonitorVo;
import com.easylinkin.linkappapi.videomonitor.entity.DeviceVideoPlaybackVo;
import com.easylinkin.linkappapi.videomonitor.mapper.DeviceVideoMonitorMapper;
import com.easylinkin.linkappapi.videomonitor.service.DeviceVideoMonitorService;
import com.easylinkin.linkappapi.webcammanage.entity.DeviceAttributeStatus;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

@Slf4j
@Service
public class DeviceVideoMonitorServiceImpl extends ServiceImpl<DeviceVideoMonitorMapper, DeviceVideoMonitor> implements DeviceVideoMonitorService {
    @Resource
    LinkappUserContextProducer linkappUserContextProducer;
    @Resource
    AlarmService alarmService;
    @Resource
    DeviceMapper deviceMapper;

    @Override
    public int batchInsert(List<DeviceVideoMonitor> list) {
        return baseMapper.batchInsert(list);
    }

    @Override
    public IPage<DeviceVideoMonitorVo> page(Page page, Device device) {
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        device.setTenantId(tenantId);
        List<DeviceVideoMonitorVo> list = baseMapper.getDeviceVideoMonitor(page, device);
        if(list == null || list.size() <= 0){
            page.setTotal(0);
            page.setRecords(null);
            return page;
        }
        for (DeviceVideoMonitorVo das:
                list) {
            if(!StringUtils.isEmpty(das.getId())){
                List<DeviceAttributeStatus> videoInfoByDevice = baseMapper.getVideoInfoByDevice(das.getId());
                if(videoInfoByDevice != null && videoInfoByDevice.size() > 0){
                    das.setChildAttributeList(videoInfoByDevice);
                }
            }
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public List<DeviceVideoMonitorVo> getDeviceVideoMonitorAll(Device device){
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        device.setTenantId(tenantId);
        List<DeviceVideoMonitorVo> list = baseMapper.getDeviceVideoMonitor(device);
        if(list == null || list.size() <= 0){
            return null;
        }
        for (DeviceVideoMonitorVo das:
                list) {
            if(!StringUtils.isEmpty(das.getId())){
                List<DeviceAttributeStatus> videoInfoByDevice = baseMapper.getVideoInfoByDevice(das.getId());
                if(videoInfoByDevice != null && videoInfoByDevice.size() > 0){
                    das.setChildAttributeList(videoInfoByDevice);
                }
            }
        }
        return list;
    }

    @Override
    public IPage<DeviceVideoMonitorVo> pageNotBind(Page page, Device device) {
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        device.setTenantId(tenantId);
        List<DeviceVideoMonitorVo> list = baseMapper.getDeviceVideoMonitorNotBind(page, device);
        if(list == null || list.size() <= 0){
            page.setTotal(0);
            page.setRecords(null);
            return page;
        }
        page.setRecords(list);
        return page;
    }

    /***
     * 批量添加设备
     * @param device
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBatchbind(Device device){
        if(device == null || device.getDeviceCodeList() == null){
            return;
        }
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        LocalDateTime date=LocalDateTime.now();
        QueryWrapper<DeviceVideoMonitor> deviceVideoMonitorQueryWrapper = new QueryWrapper<>();
        deviceVideoMonitorQueryWrapper.eq("tenant_id",tenantId);
        deviceVideoMonitorQueryWrapper.in("device_code",device.getDeviceCodeList());
        List<DeviceVideoMonitor> deviceVideoMonitorList = baseMapper.selectList(deviceVideoMonitorQueryWrapper);
        if(deviceVideoMonitorList != null && deviceVideoMonitorList.size()>0){
            List<String> collect = deviceVideoMonitorList.stream().map(m -> m.getDeviceCode()).collect(Collectors.toList());
            throw new IllegalArgumentException("设备"+collect.toString()+"已存在");
        }

        ArrayList<DeviceVideoMonitor> deviceVideoMonitors = new ArrayList<>();
        device.getDeviceCodeList().forEach(code->{
            DeviceVideoMonitor monitor=new DeviceVideoMonitor();
            monitor.setCreateTime(date);
            monitor.setDeviceCode(code);
            monitor.setTenantId(tenantId);
            deviceVideoMonitors.add(monitor);
        });

        if(deviceVideoMonitors != null && deviceVideoMonitors.size()>0){
            baseMapper.batchInsert(deviceVideoMonitors);
        }

        for (String code : device.getDeviceCodeList()) {
            // 查询设备服务
            QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
            deviceQueryWrapper.eq("code",code);
            deviceQueryWrapper.eq("tenant_id",tenantId);
            Device device1 = deviceMapper.selectOne(deviceQueryWrapper);
            if(device1 != null){
                device1.setAreaId(device.getAreaId());
                device1.setSpaceId(device.getSpaceId());
                device1.setAreaPath(device.getAreaPath());
                deviceMapper.updateById(device1);
            }
        }

    }

    /***
     * 删除
     * @param device
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Device device){
        if(device == null || device.getDeviceCodeList() == null){
            return;
        }
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        QueryWrapper<DeviceVideoMonitor> deviceVideoMonitorQueryWrapper = new QueryWrapper<>();
        deviceVideoMonitorQueryWrapper.eq("tenant_id",tenantId);
        deviceVideoMonitorQueryWrapper.in("device_code",device.getDeviceCodeList());
        baseMapper.delete(deviceVideoMonitorQueryWrapper);
        for (String code : device.getDeviceCodeList()) {
            // 查询设备服务
            QueryWrapper<Device> deviceQueryWrapper = new QueryWrapper<>();
            deviceQueryWrapper.eq("code",code);
            deviceQueryWrapper.eq("tenant_id",tenantId);
            Device device1 = deviceMapper.selectOne(deviceQueryWrapper);
            if(device1 != null){
                device1.setAreaId(null);
                device1.setSpaceId(null);
                device1.setAreaPath(null);
                deviceMapper.updateById(device1);
            }
        }
    }

    @Override
    public IPage<DeviceVideoPlaybackVo> playback(Page page,Device device){
        if(device == null){
            return page;
        }
        if(device.getDeviceCodeList() == null || device.getDeviceCodeList().size()<=0){
            String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
            device.setTenantId(tenantId);
            List<DeviceVideoMonitorVo> list = baseMapper.getDeviceVideoMonitor(device);
            if(list == null ||list.size()<=0){
                return page;
            }
            List<String> collect = list.stream().map(m -> m.getDeviceCode()).collect(Collectors.toList());
            device.setDeviceCodeList(collect);
        }
        ArrayList<DeviceVideoPlaybackVo> playbackData = getPlaybackData(device);
        if(playbackData == null){
            page.setTotal(0);
        }else{
            page.setTotal(playbackData.size());
        }
        page.setRecords(playbackData);
        return page;
    }


    private ArrayList<DeviceVideoPlaybackVo> getPlaybackData(Device device){
        if (device == null || device.getDeviceCodeList() == null || device.getDeviceCodeList().size()<=0){
            return null;
        }
        Alarm alarm=new Alarm();
        alarm.setId("30678e5bc283883f09ddcb4e2b104f67");
        alarm = alarmService.getDetail(alarm);
        if(alarm == null){
            return null;
        }
        Device deviceAlarm = alarm.getDevice();
        String deviceName=null;
        if(deviceAlarm != null){
            deviceName=deviceAlarm.getName();
        }
        ArrayList<DeviceVideoPlaybackVo> deviceVideoPlaybackVos = new ArrayList<>();
        String videoUrl = alarm.getVideoUrl();
        String finalDeviceName = deviceName;
        device.getDeviceCodeList().stream().forEach(m->{
            String code="34020000001323000122";
            long duration=258;
            if(code.equals(m)){
                DeviceVideoPlaybackVo deviceVideoPlaybackVo = new DeviceVideoPlaybackVo();
                deviceVideoPlaybackVo.setDeviceCode(code);
                deviceVideoPlaybackVo.setStartDate(DateUtil.getDate());
                deviceVideoPlaybackVo.setVideoAddress(videoUrl);
                deviceVideoPlaybackVo.setDuration(duration);
                deviceVideoPlaybackVo.setDurationFormat(DateUtil.formatSeconds(duration));
                deviceVideoPlaybackVo.setDeviceName(finalDeviceName);
                deviceVideoPlaybackVos.add(deviceVideoPlaybackVo);
            }
        });
        return deviceVideoPlaybackVos;
    }

    @Resource
    private LinkappTenantMapper linkappTenantMapper;

    @Autowired
    private DeviceServiceService deviceServiceService;

    @Resource
    private LinkageLogMapper linkageLogMapper;

//    @Scheduled(cron = "0 0/5 * * * ?")
    @Scheduled(cron = "0 0 */3 * * ?")
    public void videoDevicePictureCaptureTimer(){
        try {
            //查询所有项目
            log.info("----videoDevicePictureCaptureTimer定时任务开始执行-----------start-----------");
            List<LinkappTenant> list = linkappTenantMapper.selectByProjectId(null);
            list.removeIf(l -> "1".equals(l.getId()));
            list.forEach(l ->{
                Device device = new Device();
                device.setTenantId(l.getId());
                List<DeviceVideoMonitorVo> deviceList = baseMapper.getAllDeviceVideoMonitor(device);
                if(CollectionUtil.isNotEmpty(deviceList)){
                    deviceList.forEach(p->{
                        Device reqDevice = new Device();
                        reqDevice.setCode(p.getDeviceCode());
                        reqDevice.setTenantId(p.getTenantId());
                        sendPictureCapture(reqDevice);
                    });
                }
            });
            log.info("----videoDevicePictureCaptureTimer定时任务完成-----------end-----------");
        }catch (Exception e){
            log.error("----videoDevicePictureCaptureTimer定时任务完成-----------error-----------",e);
        }

    }

    private void sendPictureCapture(Device device){
        Map<String, Object> downParameter = new HashMap<>(8);
        Map<String, Object> parameter = new HashMap<>(8);
        downParameter.put("service_id","picture_capture");
        downParameter.put("device_id",device.getCode());
        parameter.put("operation_command",1);
        downParameter.put("parameter",parameter);
        log.info("推送指令参数：" + JSON.toJSONString(downParameter));
        ApiDownResultDTO send = deviceServiceService.send(downParameter);
        log.info("ApiDownResultDTO--响应结果" + JSON.toJSONString(send));
        saveExecuteLog(send, "videoDevicePictureCaptureTimer", device.getCode(), device.getTenantId());
        downParameter.clear();
    }

    private void saveExecuteLog(ApiDownResultDTO send, String jobName, String deviceCode, String tenantId){
        LinkageLog ll = new LinkageLog();
        ll.setSendTime(new Date());
        ll.setSaveTime(new Date());
        ll.setDeviceCode(deviceCode);
        ll.setRuleEngineId(jobName);
        ll.setTenantId(tenantId);
        ll.setType(2);
        String code = send.getCode();
        ll.setState("0".equals(code) ? true : false);
        ll.setResultCode(send.getCode());
        ll.setResultMsg(send.getMsg());
        ll.setRequestId(send.getRequestId());
        linkageLogMapper.insert(ll);
    }
}
